package com.exam.util.loader;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import zuojie.esql.Esql;

import com.exam.operation.OperationContext;

/**
 * Excel数据装载器
 * 
 * <p>
 * 第一行是标题行，以后是数据行。
 * 
 * <p>
 * {#link LoadHandler}是具体的数据处理器
 * 
 * @author zuojie
 * 
 */
public class ExcelLoader implements Loader
{
	private static final DateFormat df = new SimpleDateFormat("yyyy-MM");

	private LoaderHandler handler;
	private File file;
	private Esql esql;

	private int failCount = 0;
	private List<String> messages = new ArrayList<String>();

	private int blankSheet;

	public ExcelLoader(LoaderHandler handler, File file, Esql esql)
	{
		this.handler = handler;
		this.file = file;
		this.blankSheet = 0;
		this.esql = esql;
	}

	public void load() throws Exception
	{
		String fileName = file.getCanonicalPath();
		if (!".xls".equalsIgnoreCase(fileName.substring(fileName.lastIndexOf("."))))
		{
			throw new Exception(fileName + "文件格式错误!");
		}

		InputStream input = null;
		try
		{
			input = new FileInputStream(file);
			HSSFWorkbook workbook = new HSSFWorkbook(input);
			for (int i = 0; i < workbook.getNumberOfSheets(); i++)
			{
				importSheet(workbook.getSheetAt(i));
			}
			if (blankSheet == workbook.getNumberOfSheets())
			{
				throw new Exception(fileName + "文件没有内容!");
			}
		}
		catch (Exception e)
		{
			
			messages.add("导入失败,请再次检查文件数据格式:" + e.getMessage());
			failCount = Integer.MAX_VALUE;
		}
		finally
		{
			if (input != null)
			{
				try
				{
					input.close();
				}
				catch (Exception e)
				{
				}
			}
		}
	}

	private void importSheet(HSSFSheet sheet) throws Exception
	{
		String[] title;

		int rows = sheet.getLastRowNum() + 1;
		if (rows <= 1)
		{
			blankSheet++;
			return;
		}

		// 先读标题
		HSSFRow row = sheet.getRow(0);
		int m = row.getFirstCellNum();
		int n = row.getLastCellNum();
		title = new String[n];
		for (int i = m; i < n; i++)
		{
			HSSFCell cell = row.getCell(i);
			if (cell == null)
				title[i] = "";						//表头为空，此列数据直接忽略
			else
				title[i] = cell.getRichStringCellValue().getString();
		}

		// 再读入每行
		for (int i = 1; i < rows; i++)
		{
			row = sheet.getRow(i);

			Map<String, String> map = new HashMap<String, String>();

			try
			{
				for (int j = m; j < n; j++)
				{
					HSSFCell cell = row.getCell(j);
					//2010.7.30，方智阳在此处增加trim(), 防止数据有空格
					String cellContent = getCellString(cell);
					if (cellContent != null) cellContent = cellContent.trim();
					map.put(title[j].trim(), cellContent);
				}

			
				handler.load(map, esql);
			}
			catch (Exception e)
			{
				failCount++;
				messages.add(String.format("导入错误: 第%d行: %s", i + 1, e.getMessage()));
			}
		}

		///** 人员导入部分行出错，其他行正常导入事务不回滚 */
		if (failCount > 0)
		{
			///** 如果不是导入人员，就回滚 */
			//if (!handler.getClass().getName().equalsIgnoreCase("UserLoadHandler"))
				OperationContext.getContext().setRollback(true);
		}
	}

	public List<String> getMessages()
	{
		return messages;
	}

	public int getFailCount()
	{
		return failCount;
	}

	private String getCellString(HSSFCell cell)
	{
		String value = null;
		if(cell == null)
			return value;

		int type = cell.getCellType();
		
		switch (type)
		{
		case HSSFCell.CELL_TYPE_BLANK:
			value = "";
			break;
		case HSSFCell.CELL_TYPE_BOOLEAN:
			value = Boolean.toString(cell.getBooleanCellValue());
			break;
		case HSSFCell.CELL_TYPE_NUMERIC:
			// 判断当前的cell是否为Date
			if (HSSFDateUtil.isCellDateFormatted(cell))
			{
				// 如果是Date类型则，取得该Cell的Date值
				value = df.format(cell.getDateCellValue());
			}
			// 如果不是则可能是其它数值类型：整数、浮点数, 交给应用逻辑处理
			else
			{
				String data = Double.toString(cell.getNumericCellValue());
				BigDecimal big = new BigDecimal(data);
				
				data = String.valueOf(big.intValue());
				String[] dataArr = data.split("\\.");
				//整数
				if (dataArr.length > 1 && Double.valueOf(dataArr[1]) == 0)
					value = dataArr[0];
				//浮点数
				else
					value = data;
			}
			break;
		case HSSFCell.CELL_TYPE_STRING:
			value = cell.getRichStringCellValue().getString();
			break;
		default:
			throw new IllegalStateException("未知的单元类型: " + type);
		}

		return value;			
	}
}
